package day64;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.junit.Test;

public class ReflectTest {

	@Test
	public void testClass() throws ClassNotFoundException {
		// 1. Class.forName(包名.类型);
		Class clazz1 = Class.forName("day64.Person");
		// 2. 类名.class
		Class clazz2 = Person.class;
		// 3. 对象.getClass();
		Person person = new Person();
		Class clazz3 = person.getClass();
		
		// 一个类的字节码对象在内存中只有一份
		System.out.println(clazz1 == clazz2);// true
		System.out.println(clazz2 == clazz3);// true
		Constructor[] constructors = clazz1.getConstructors();
	}
	
	@Test
	public void testConstructor() {
		Class clazz = Person.class;
		// 所有public的构造方法
		Constructor[] constructors = clazz.getConstructors();
		for (Constructor constructor : constructors) {
			System.out.println(constructor);
		}
		System.out.println("----------------");
		// 得到所有的构造方法，包括private
		Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
		for (Constructor constructor : declaredConstructors) {
			System.out.println(constructor);
			System.out.println(constructor.getName());// 构造方法的名字
			System.out.println(constructor.getModifiers());// public(1)/private(2)
		}
	}
	
	@Test
	public void testConstructor2() throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Class clazz = Person.class;
		Constructor constructor = clazz.getDeclaredConstructor(String.class);
		System.out.println(constructor);
		Person person = (Person)constructor.newInstance("张三");// new Person("张三")
		System.out.println(person);
	}
	
	@Test
	public void testConstructor3() throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Class clazz = Person.class;
		Constructor constructor = clazz.getDeclaredConstructor(String.class, Integer.class);
		System.out.println(constructor);
		// Person person = new Person("张三", 23);
		Person person = (Person)constructor.newInstance("张三", 23);
		System.out.println(person);
	}
	
	@Test
	public void testMethod() throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		// Person person = new Person();
		// person.setName("张三");
		
		Class clazz = Person.class;
		// 得到无参构造方法
		Constructor constructor = clazz.getConstructor();
		// Person person = new Person(); 调用newInstance实例化对象
		Person person = (Person)constructor.newInstance();
		Method method = clazz.getDeclaredMethod("setName", String.class);
		// 加上这个之后私有的方法也可以访问
		method.setAccessible(true);
		// person.setName("张三");
		// 第一个参数是person对象，第二个参数是这个方法的参数
		method.invoke(person, "张三");
		System.out.println(person);
	}
	
	
}
